package com.companyName.sample.data.config;

import com.companyName.sample.data.BaseMapper;
import org.apache.ibatis.session.SqlSessionFactory;
import org.aspectj.lang.annotation.AdviceName;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.Advice;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.util.StringUtils;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * 修正MybtisAutoConfig的bug
 * (配置config属性后其他属性会被忽略)
 * @author guojun
 */
@Configuration
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceConfig.class)
//@MapperScan(basePackages = "sample.spring.ibatis.dao", sqlSessionFactoryRef = "sqlSessionFactory")
@MapperScan(basePackages={"com.companyName.sample.data.mapper"})
public class MybatisConfig {
	private Logger log = LoggerFactory.getLogger(MybatisConfig.class);

	@Autowired
	private MybatisProperties properties;

	@Autowired
	private ResourceLoader resourceLoader = new DefaultResourceLoader();


	@Bean
	@ConditionalOnMissingBean
	public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
		log.info("加载MyBatis配置文件:{}", this.properties.getConfig());
		SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
		factory.setDataSource(dataSource);
		if (StringUtils.hasText(this.properties.getConfig())) {
			factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfig()));
		}
		factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
		factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
		factory.setMapperLocations(this.properties.getMapperLocations());
		return factory.getObject();
	}

	@Bean
	@ConditionalOnMissingBean
	public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
		return new SqlSessionTemplate(sqlSessionFactory);
	}

/*	@Bean
	@Override
	public PlatformTransactionManager annotationDrivenTransactionManager() {
		return new DataSourceTransactionManager(dataSource);
	}*/


/*	@Bean
	public TransactionInterceptor transactionInterceptor() {
		Properties attributes = new Properties();
		attributes.setProperty("create*", "PROPAGATION_REQUIRED");
		TransactionInterceptor txAdvice = new TransactionInterceptor(annotationDrivenTransactionManager(), attributes);
		return txAdvice;
	}
	@Bean
	public Advisor transactionAdvisor() {
		AspectJExpressionPointcutAdvisor aspectJExpressionPointcutAdvisor = new AspectJExpressionPointcutAdvisor();
		aspectJExpressionPointcutAdvisor.setExpression("execution(* com.companyName.sample.*.*.*.*(..))");
		aspectJExpressionPointcutAdvisor.setAdvice(transactionInterceptor());
		return aspectJExpressionPointcutAdvisor;
	}*/
}
